import os
import time

from flask import Blueprint, render_template, request, redirect, url_for, jsonify, session, g
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename

from apps.article.models import ArticleType, Article
from apps.user.models import User, Photo, AboutMe, MessageBoard
from apps.user.smssend import SmsSendAPIDemo
from apps.utils.util import upload_qiniu, delete_qiniu, user_type, send_mes
from exts import db, cache
from settings import Config

user_bp = Blueprint('user', __name__, url_prefix='/user')

required_login_list = ['/user/center',
                       '/user/change',
                       '/article/publish',
                       '/user/upload_photo',
                       '/user/myphoto',
                       '/user/photo_del',
                       '/article/add_comment',
                        '/user/aboutchange',
                       '/user/self',
                       ]
# 图片的扩展名
ALLOWED_EXTENSIONS = ['jpg', 'png', 'gif', 'bmp']


@user_bp.before_app_first_request
def first_request():
    pass

@user_bp.before_app_request
def before_request1():
    if request.path in required_login_list:
        uid = session.get('uid')
        if not uid:
            return render_template('user/login.html')
        else:
            user = User.query.get(uid)
            g.user = user


@user_bp.after_app_request
def after_request_test(response):
    return response


@user_bp.teardown_app_request
def teardown_request_test(response):
    return response


@user_bp.app_template_filter('cdecode1')
def content_decode1(content):
    content = content.decode('utf-8')
    return content


# 首页
@user_bp.route('/')
@cache.cached(timeout=50)
def index():
    user, types = user_type()
    page = int(request.args.get('page', 1))
    search = request.args.get('search', '')
    if search:
        pagination = Article.query.filter(Article.title.contains(search)).\
            order_by(-Article.pdatetime).\
            paginate(page=page, per_page=3)
    else:
        pagination = Article.query.order_by(-Article.pdatetime).\
            paginate(page=page, per_page=3)

    params = {
        'user': user,
        'types': types,
        'pagination': pagination,
        'search': search
    }
    return render_template('user/index.html', **params)


# 个人首页
@user_bp.route('/self')
def index_self():
    user, types = user_type()
    page = int(request.args.get('page', 1))
    pagination = Article.query.filter(Article.user_id == g.user.id).order_by(-Article.pdatetime). \
        paginate(page=page, per_page=3)

    params = {
        'user': user,
        'types': types,
        'pagination': pagination,
    }
    return render_template('user/index.html', **params)


# 用户注册
@user_bp.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        repassword = request.form.get('repassword')
        phone = request.form.get('phone')
        email = request.form.get('email')
        if password == repassword:
            user = User()
            user.username = username
            # 使用自带的函数实现加密：generate_password_hash
            user.password = generate_password_hash(password)
            user.phone = phone
            user.email = email
            db.session.add(user)
            db.session.commit()
            return redirect(url_for('user.login'))
    return render_template('user/register.html')

# 用户名验证
@user_bp.route('/checkuname', methods=['GET', 'POST'])
def check_uname():
    uname = request.args.get('username')
    user = User.query.filter(User.username == uname).all()
    if len(user) > 0:
        return jsonify(code=400, msg='此用户名已被使用')
    else:
        return jsonify(code=200, msg='此用户名可用')


# 手机号码验证
@user_bp.route('/checkphone', methods=['GET', 'POST'])
def check_phone():
    phone = request.args.get('phone')
    user = User.query.filter(User.phone == phone).all()
    print(user)
    # code: 400 不能用    200 可以用
    if len(user) > 0:
        return jsonify(code=400, msg='此号码已被注册')
    else:
        return jsonify(code=200, msg='此号码可用')


# 用户登录
@user_bp.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        f = request.args.get('f')
        if f == '1':  # 用户名或者密码
            username = request.form.get('username')
            password = request.form.get('password')
            users = User.query.filter(User.username == username).all()
            for user in users:
                if check_password_hash(user.password, password):
                    session['uid'] = user.id
                    return redirect(url_for('user.index'))
            else:
                return render_template('user/login.html', msg='用户名或者密码有误')
        elif f == '2':  # 手机号码与验证码
            phone = request.form.get('phone')
            code = request.form.get('code')
            valid_code = cache.get(phone)
            if code == valid_code:
                user = User.query.filter(User.phone == phone).first()
                if user:
                    session['uid'] = user.id
                    return redirect(url_for('user.index'))
                else:
                    return render_template('user/login.html', msg='此号码未注册')
            else:
                return render_template('user/login.html', msg='验证码有误！')

    return render_template('user/login.html')


# 用户退出
@user_bp.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('user.index'))

# 发送短信息
@user_bp.route('/sendMsg')
def send_message():
    phone = request.args.get('phone')
    ret,code = send_mes(phone)

    if ret is not None:
        if ret["code"] == 200:
            cache.set(phone,code,timeout=180)
            return jsonify(code=200, msg='短信发送成功！')
        else:
            print("ERROR: ret.code=%s,msg=%s" % (ret['code'], ret['msg']))
            return jsonify(code=400, msg='短信发送失败！')


# 用户中心
@user_bp.route('/center')
def user_center():
    types = ArticleType.query.all()
    photos = Photo.query.filter(Photo.user_id == g.user.id).all()
    return render_template('user/center.html', user=g.user, types=types, photos=photos)


@user_bp.route('/aboutchange', methods=['GET', 'POST'])
def about_me_change():
    about = AboutMe.query.filter(AboutMe.user_id == g.user.id).first()
    content = request.form.get('about')
    if about:
        about.content = content.encode('utf-8')
        about.user_id = g.user.id
    else:
        about = AboutMe()
        about.content = content.encode('utf-8')
        about.user_id = g.user.id
        db.session.add(about)
    db.session.commit()

    return redirect(url_for('user.user_center'))


# 用户信息修改
@user_bp.route('/change', methods=['GET', 'POST'])
def user_change():
    if request.method == 'POST':
        username = request.form.get('username')
        phone = request.form.get('phone')
        email = request.form.get('email')
        icon = request.files.get('icon')
        user = g.user
        if icon:
            icon_name = icon.filename  # 属性： filename 用户获取文件的名字
            suffix = icon_name.rsplit('.')[-1]
            if suffix in ALLOWED_EXTENSIONS:
                icon_name = secure_filename(icon_name)  # 保证文件名是符合python的命名规则
                file_path = os.path.join(Config.UPLOAD_ICON_DIR, icon_name)
                icon.save(file_path)  # 方法:  save(保存路径)
                user.icon = f'upload/icon/{icon.filename}'
            else:
                return render_template('user/center.html', user=g.user, msg='必须是扩展名是：jpg,png,gif,bmp格式')
        user.username = username
        user.phone = phone
        user.email = email
        db.session.commit()
        return redirect(url_for('user.user_center'))

    return render_template('user/center.html', user=g.user)


# 上传照片
@user_bp.route('/upload_photo', methods=['GET', 'POST'])
def upload_photo():
    # 获取上传的内容
    photo = request.files.get('photo')  # FileStorage
    # photo.filename,photo.save(path)
    # 工具模块中封装方法
    ret, info = upload_qiniu(photo)
    if info.status_code == 200:
        photo = Photo()
        photo.photo_name = ret['key']
        photo.user_id = g.user.id
        db.session.add(photo)
        db.session.commit()
        return '上传成功！'
    else:
        return '上传失败！'


# 删除相册图片
@user_bp.route('/photo_del')
def photo_del():
    pid = request.args.get('pid')
    photo = Photo.query.get(pid)
    filename = photo.photo_name
    # 封装好的一个删除七牛存储文件的函数
    info = delete_qiniu(filename)
    # 判断状态码
    if info.status_code == 200:
        # 删除数据库的内容
        db.session.delete(photo)
        db.session.commit()
        return redirect(url_for('user.user_center'))
    else:
        return render_template('500.html', err_msg='删除相册图片失败！')


# 我的相册
@user_bp.route('/myphoto')
def myphoto():
    user,types = user_type()
    photos = Photo.query.filter(Photo.user_id == user.id).paginate(page=1, per_page=3)
    return render_template('user/myphoto.html', photos=photos, user=user, types=types)


# 留言板
@user_bp.route('/board', methods=['GET', 'POST'])
def show_board():
    # 获取登录用户信息
    user, types = user_type()
    uid = None
    if user:
        uid = user.id

    # 查询所有的留言内容
    page = int(request.args.get('page', 1))
    boards = MessageBoard.query.order_by(-MessageBoard.mdatetime).paginate(page=page, per_page=5)
    # 判断请求方式
    if request.method == 'POST':
        content = request.form.get('board')
        msg_board = MessageBoard()
        msg_board.content = content
        if uid:
            msg_board.user_id = uid
        db.session.add(msg_board)
        db.session.commit()
        return redirect(url_for('user.show_board'))
    return render_template('user/board.html', user=user, boards=boards, types=types)


# 留言删除
@user_bp.route('/board_del')
def delete_board():
    bid = request.args.get('bid')
    if bid:
        msgboard = MessageBoard.query.get(bid)
        db.session.delete(msgboard)
        db.session.commit()
        return redirect(url_for('user.user_center'))


@user_bp.route('/error')
def test_error():
    referer = request.headers.get('Referer', None)
    return render_template('500.html', err_msg='有误', referer=referer)
